package se.webbzon.boltzmann.game.object.dialogue.word;

import java.awt.Dimension;

import se.webbzon.boltzmann.game.object.dialogue.AbstractDialogue;
import se.webbzon.boltzmann.game.object.dialogue.AbstractDialogueItem;
import se.webbzon.boltzmann.game.object.dialogue.layout.DialogueLayout;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;

public abstract class AbstractDialogueWord extends AbstractDialogueItem {
	
	// The dialogue layout used for this dialogue word
	private final DialogueLayout layout;
	
	// The last visible character (1 is the first character)
	private int character;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public AbstractDialogueWord(DialogueLayout layout, 
								Appearance3D appearance) {
		super(appearance);
		this.layout = layout;
		character = 0;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Copies the dimension of this word when it is fully printed
	 * to the provided dimension object. This method is called when 
	 * the words of the dialogue are positioned, that is after the 
	 * method onUpdateWord() has been called. **/
	public abstract void getDimension(Dimension d);
	
	/** Returns true if the word is a newline character (\n).**/
	public abstract boolean isNewLine();
	
	/** Returns the word as a string. This functions is ignored
	 * if the word is a new line (\n), in other words if the
	 * method isNewLine() returns true. **/
	public abstract String getWord();
	
	/** This method is invoked before the position of all the words 
	 * in the dialogue are positioned. This gives the user a chance
	 * to change the content of a word. **/
	public abstract void onUpdateWord(AbstractDialogue dialogue);
	
	/** This method is invoked when a new character of the word should 
	 * be displayed in the provided dialogue. The input parameter is 
	 * the index of last character to display in the word. 
	 * The index of the first character is 1. If the provided character
	 * is zero then the word should be hidden. **/
	public abstract void onShowCharacter(AbstractDialogue dialogue, int character);
	
	/** This method is invoked when all the characters of the word 
	 * should be displayed in the provided dialogue. **/
	public abstract void onShowAllCharacters(AbstractDialogue dialogue);
	
	/** Returns the dialogue layout of this dialogue word. **/
	public final DialogueLayout getLayout() {
		return layout;
	}
	
	/** Returns the index of the current last visible character. 
	 * The index of the character is in the range 0 to getWord().length-1. **/
	public final int getCharacter() {
		return character;
	}
	
	/** Sets the last visible character in the dialogue word. **/
	public final void setCharacter(AbstractDialogue dialogue, int character) {
		int length = getWord().length();
		this.character = Math.max(0, Math.min(character, length));
		onShowCharacter(dialogue,this.character);
	}
	
	public final void showAllCharacters(AbstractDialogue dialogue) {
		this.character = getWord().length();
		onShowAllCharacters(dialogue);
	}
	
	/** Returns true if the whole word is visible. **/
	public final boolean isAllVisible() {
		return (character == getWord().length());
	}

}
